#include "stdafx.h"
#include "CppUnitTest.h"

//#include "../Geometry/Vector3d.h"
//#include "../Geometry/Vector3d.cpp"
//
#include "../Geometry/Line3d.h"
//
//#include "../Geometry/Point3d.h"

#include "../Geometry/Triangle3d.h"
#include "../Geometry/Triangle3d.cpp"

#include "../Geometry/Segment3d.h"
//#include "../Geometry/Segment3d.cpp"

using Geometry::Vector3d;
using Geometry::Line3d;
using Geometry::Point3d;
using Geometry::Triangle3d;
using Geometry::Segment3d;

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace GeometryTests
  {
  TEST_CLASS(UnitTestTriangle3d)
    {
    public:
      TEST_METHOD(ShouldContainPointsCorrectly2D)
        {
        Point3d pt1(0, 0, 0);
        Point3d pt2(10, 0, 0);
        Point3d pt3(0, 10, 0);
        
        Triangle3d tr(pt1, pt2, pt3);

        Point3d p_in_1(2, 2, 0);
        Point3d p_in_2(3, 2, 0);
        Point3d p_on_1(0, 1, 0);
        Point3d p_on_2(0, 10, 0);

        Point3d p_out_1(2, 2, 1);
        Point3d p_out_2(20, 10, 0);

        Assert::IsTrue(tr.ContainsPoint(p_in_1));
        Assert::IsTrue(tr.ContainsPoint(p_in_2));
        Assert::IsTrue(tr.ContainsPoint(p_on_1));
        Assert::IsTrue(tr.ContainsPoint(p_on_2));

        Assert::IsFalse(tr.ContainsPoint(p_out_1));
        Assert::IsFalse(tr.ContainsPoint(p_out_1));
        }

      TEST_METHOD(ShouldContainPointsCorrectly3D)
        {
        Point3d pt1(0, 0, 10);
        Point3d pt2(10, 0, 0);
        Point3d pt3(0, 10, 0);

        Triangle3d tr(pt1, pt2, pt3);

        Point3d p_in_1(0, 5, 5);
        Point3d p_in_2(10.0/3, 10.0/3, 10.0/3);
        Point3d p_on_1(10, 0, 0);
        Point3d p_on_2(0, 10, 0);

        Point3d p_out_1(2, 2, -1);
        Point3d p_out_2(20, 10, 0);

        Assert::IsTrue(tr.ContainsPoint(p_in_1));
        Assert::IsTrue(tr.ContainsPoint(p_in_2));
        Assert::IsTrue(tr.ContainsPoint(p_on_1));
        Assert::IsTrue(tr.ContainsPoint(p_on_2));

        Assert::IsFalse(tr.ContainsPoint(p_out_1));
        Assert::IsFalse(tr.ContainsPoint(p_out_1));
        }

      TEST_METHOD(ShouldProjectCorrectly)
        {
        Line3d l = Line3d(Point3d(0, 0, 0), Point3d(1, 0, 0));
        Triangle3d tr = Triangle3d(Point3d(5, 0, 0), Point3d(1, 4, 0), Point3d(0, 0, 0));

        Segment3d expected = Segment3d(Point3d(0, 0, 0), Point3d(5, 0, 0));
        Segment3d actual = Geometry::TriangleProjectLine3d(tr, l);

        Assert::IsTrue(expected.GetBegin() == actual.GetBegin());
        Assert::IsTrue(expected.GetEnd() == actual.GetEnd());
        }

      TEST_METHOD(ShouldIntersectCorrectly)
        {

        }

    };
  }